﻿namespace AutoRevit.Event;

/// <summary>
/// 
/// </summary>
public static class ExternalEventTaskExtensions
{
    /// <summary>
    /// 执行外部事件任务
    /// </summary>
    /// <typeparam name="T1"></typeparam>
    /// <param name="revitTask"></param>
    /// <param name="param1"></param>
    /// <param name="act"></param>
    /// <returns></returns>
    public static Task RunAsync<T1>(this ExternalEventTask revitTask, T1 param1, Action<UIApplication, T1> act)
    {
        revitTask.tcs = new TaskCompletionSource<object>();
        Func<UIApplication, T1, object> f = (app, p1) => { act(app, p1); return new object(); };
        revitTask.handler.SetFunc(f, param1);
        revitTask.externalEvent.Raise();
        return revitTask.tcs.Task;
    }

    /// <summary>
    /// 执行外部事件任务
    /// </summary>
    /// <typeparam name="T1"></typeparam>
    /// <typeparam name="T2"></typeparam>
    /// <param name="revitTask"></param>
    /// <param name="param1"></param>
    /// <param name="param2"></param>
    /// <param name="act"></param>
    /// <returns></returns>
    public static Task RunAsync<T1, T2>(this ExternalEventTask revitTask, T1 param1, T2 param2, Action<UIApplication, T1, T2> act)
    {
        revitTask.tcs = new TaskCompletionSource<object>();
        Func<UIApplication, T1, T2, object> f = (app, p1, p2) => { act(app, p1, p2); return new object(); };
        revitTask.handler.SetFunc(f, param1, param2);
        revitTask.externalEvent.Raise();
        return revitTask.tcs.Task;
    }

    /// <summary>
    /// 执行外部事件任务
    /// </summary>
    /// <typeparam name="T1"></typeparam>
    /// <typeparam name="T2"></typeparam>
    /// <typeparam name="T3"></typeparam>
    /// <param name="revitTask"></param>
    /// <param name="param1"></param>
    /// <param name="param2"></param>
    /// <param name="param3"></param>
    /// <param name="act"></param>
    /// <returns></returns>
    public static Task RunAsync<T1, T2, T3>(this ExternalEventTask revitTask, T1 param1, T2 param2, T3 param3, Action<UIApplication, T1, T2, T3> act)
    {
        revitTask.tcs = new TaskCompletionSource<object>();
        Func<UIApplication, T1, T2, T3, object> f = (app, p1, p2, p3) => { act(app, p1, p2, p3); return new object(); };
        revitTask.handler.SetFunc(f, param1, param2, param3);
        revitTask.externalEvent.Raise();
        return revitTask.tcs.Task;
    }

    /// <summary>
    /// 执行外部事件任务
    /// </summary>
    /// <typeparam name="T1"></typeparam>
    /// <typeparam name="T2"></typeparam>
    /// <typeparam name="T3"></typeparam>
    /// <typeparam name="T4"></typeparam>
    /// <param name="revitTask"></param>
    /// <param name="param1"></param>
    /// <param name="param2"></param>
    /// <param name="param3"></param>
    /// <param name="param4"></param>
    /// <param name="act"></param>
    /// <returns></returns>
    public static Task RunAsync<T1, T2, T3, T4>(this ExternalEventTask revitTask, T1 param1, T2 param2, T3 param3, T4 param4, Action<UIApplication, T1, T2, T3, T4> act)
    {
        revitTask.tcs = new TaskCompletionSource<object>();
        Func<UIApplication, T1, T2, T3, T4, object> f = (app, p1, p2, p3, p4) => { act(app, p1, p2, p3, p4); return new object(); };
        revitTask.handler.SetFunc(f, param1, param2, param3, param4);
        revitTask.externalEvent.Raise();
        return revitTask.tcs.Task;
    }

    /// <summary>
    /// 执行外部事件任务
    /// </summary>
    /// <typeparam name="T1"></typeparam>
    /// <typeparam name="T2"></typeparam>
    /// <typeparam name="T3"></typeparam>
    /// <typeparam name="T4"></typeparam>
    /// <typeparam name="T5"></typeparam>
    /// <param name="revitTask"></param>
    /// <param name="param1"></param>
    /// <param name="param2"></param>
    /// <param name="param3"></param>
    /// <param name="param4"></param>
    /// <param name="param5"></param>
    /// <param name="act"></param>
    /// <returns></returns>
    public static Task RunAsync<T1, T2, T3, T4, T5>(this ExternalEventTask revitTask, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, Action<UIApplication, T1, T2, T3, T4, T5> act)
    {
        revitTask.tcs = new TaskCompletionSource<object>();
        Func<UIApplication, T1, T2, T3, T4, T5, object> f = (app, p1, p2, p3, p4, p5) => { act(app, p1, p2, p3, p4, p5); return new object(); };
        revitTask.handler.SetFunc(f, param1, param2, param3, param4, param5);
        revitTask.externalEvent.Raise();
        return revitTask.tcs.Task;
    }

    /// <summary>
    /// 执行外部事件任务
    /// </summary>
    /// <typeparam name="T1"></typeparam>
    /// <typeparam name="T2"></typeparam>
    /// <typeparam name="T3"></typeparam>
    /// <typeparam name="T4"></typeparam>
    /// <typeparam name="T5"></typeparam>
    /// <typeparam name="T6"></typeparam>
    /// <param name="revitTask"></param>
    /// <param name="param1"></param>
    /// <param name="param2"></param>
    /// <param name="param3"></param>
    /// <param name="param4"></param>
    /// <param name="param5"></param>
    /// <param name="param6"></param>
    /// <param name="act"></param>
    /// <returns></returns>
    public static Task RunAsync<T1, T2, T3, T4, T5, T6>(this ExternalEventTask revitTask, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, Action<UIApplication, T1, T2, T3, T4, T5, T6> act)
    {
        revitTask.tcs = new TaskCompletionSource<object>();
        Func<UIApplication, T1, T2, T3, T4, T5, T6, object> f = (app, p1, p2, p3, p4, p5, p6) => { act(app, p1, p2, p3, p4, p5, p6); return new object(); };
        revitTask.handler.SetFunc(f, param1, param2, param3, param4, param5, param6);
        revitTask.externalEvent.Raise();
        return revitTask.tcs.Task;
    }

    /// <summary>
    /// 执行外部事件任务
    /// </summary>
    /// <typeparam name="T1"></typeparam>
    /// <typeparam name="T2"></typeparam>
    /// <typeparam name="T3"></typeparam>
    /// <typeparam name="T4"></typeparam>
    /// <typeparam name="T5"></typeparam>
    /// <typeparam name="T6"></typeparam>
    /// <typeparam name="T7"></typeparam>
    /// <param name="revitTask"></param>
    /// <param name="param1"></param>
    /// <param name="param2"></param>
    /// <param name="param3"></param>
    /// <param name="param4"></param>
    /// <param name="param5"></param>
    /// <param name="param6"></param>
    /// <param name="param7"></param>
    /// <param name="act"></param>
    /// <returns></returns>
    public static Task RunAsync<T1, T2, T3, T4, T5, T6, T7>(this ExternalEventTask revitTask, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, Action<UIApplication, T1, T2, T3, T4, T5, T6, T7> act)
    {
        revitTask.tcs = new TaskCompletionSource<object>();
        Func<UIApplication, T1, T2, T3, T4, T5, T6, T7, object> f = (app, p1, p2, p3, p4, p5, p6, p7) => { act(app, p1, p2, p3, p4, p5, p6, p7); return new object(); };
        revitTask.handler.SetFunc(f, param1, param2, param3, param4, param5, param6, param7);
        revitTask.externalEvent.Raise();
        return revitTask.tcs.Task;
    }


    //-------------------------------------------------------------------------------------------------------------------------------------------

    /// <summary>
    /// 执行可以返回数据的外部事件任务
    /// </summary>
    /// <typeparam name="T1"></typeparam>
    /// <typeparam name="TResult"></typeparam>
    /// <param name="revitTask"></param>
    /// <param name="param1"></param>
    /// <param name="func"></param>
    /// <returns></returns>
    public static Task<TResult> RunAsync<T1, TResult>(this ExternalEventTask revitTask, T1 param1, Func<UIApplication, T1, TResult> func)
    {
        revitTask.tcs = new TaskCompletionSource<object>();
        var task = Task.Run(async () => (TResult)await revitTask.tcs.Task);
        revitTask.handler.SetFunc(func, param1);
        revitTask.externalEvent.Raise();
        return task;
    }

    /// <summary>
    /// 执行可以返回数据的外部事件任务
    /// </summary>
    /// <typeparam name="T1"></typeparam>
    /// <typeparam name="T2"></typeparam>
    /// <typeparam name="TResult"></typeparam>
    /// <param name="revitTask"></param>
    /// <param name="param1"></param>
    /// <param name="param2"></param>
    /// <param name="func"></param>
    /// <returns></returns>
    public static Task<TResult> RunAsync<T1, T2, TResult>(this ExternalEventTask revitTask, T1 param1, T2 param2, Func<UIApplication, T1, T2, TResult> func)
    {
        revitTask.tcs = new TaskCompletionSource<object>();
        var task = Task.Run(async () => (TResult)await revitTask.tcs.Task);
        revitTask.handler.SetFunc(func, param1, param2);
        revitTask.externalEvent.Raise();
        return task;
    }

    /// <summary>
    /// 执行可以返回数据的外部事件任务
    /// </summary>
    /// <typeparam name="T1"></typeparam>
    /// <typeparam name="T2"></typeparam>
    /// <typeparam name="T3"></typeparam>
    /// <typeparam name="TResult"></typeparam>
    /// <param name="revitTask"></param>
    /// <param name="param1"></param>
    /// <param name="param2"></param>
    /// <param name="param3"></param>
    /// <param name="func"></param>
    /// <returns></returns>
    public static Task<TResult> RunAsync<T1, T2, T3, TResult>(this ExternalEventTask revitTask, T1 param1, T2 param2, T3 param3, Func<UIApplication, T1, T2, T3, TResult> func)
    {
        revitTask.tcs = new TaskCompletionSource<object>();
        var task = Task.Run(async () => (TResult)await revitTask.tcs.Task);
        revitTask.handler.SetFunc(func, param1, param2, param3);
        revitTask.externalEvent.Raise();
        return task;
    }

    /// <summary>
    /// 执行可以返回数据的外部事件任务
    /// </summary>
    /// <typeparam name="T1"></typeparam>
    /// <typeparam name="T2"></typeparam>
    /// <typeparam name="T3"></typeparam>
    /// <typeparam name="T4"></typeparam>
    /// <typeparam name="TResult"></typeparam>
    /// <param name="revitTask"></param>
    /// <param name="param1"></param>
    /// <param name="param2"></param>
    /// <param name="param3"></param>
    /// <param name="param4"></param>
    /// <param name="func"></param>
    /// <returns></returns>
    public static Task<TResult> RunAsync<T1, T2, T3, T4, TResult>(this ExternalEventTask revitTask, T1 param1, T2 param2, T3 param3, T4 param4, Func<UIApplication, T1, T2, T3, T4, TResult> func)
    {
        revitTask.tcs = new TaskCompletionSource<object>();
        var task = Task.Run(async () => (TResult)await revitTask.tcs.Task);
        revitTask.handler.SetFunc(func, param1, param2, param3, param4);
        revitTask.externalEvent.Raise();
        return task;
    }

    /// <summary>
    /// 执行可以返回数据的外部事件任务
    /// </summary>
    /// <typeparam name="T1"></typeparam>
    /// <typeparam name="T2"></typeparam>
    /// <typeparam name="T3"></typeparam>
    /// <typeparam name="T4"></typeparam>
    /// <typeparam name="T5"></typeparam>
    /// <typeparam name="TResult"></typeparam>
    /// <param name="revitTask"></param>
    /// <param name="param1"></param>
    /// <param name="param2"></param>
    /// <param name="param3"></param>
    /// <param name="param4"></param>
    /// <param name="param5"></param>
    /// <param name="func"></param>
    /// <returns></returns>
    public static Task<TResult> RunAsync<T1, T2, T3, T4, T5, TResult>(this ExternalEventTask revitTask, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, Func<UIApplication, T1, T2, T3, T4, T5, TResult> func)
    {
        revitTask.tcs = new TaskCompletionSource<object>();
        var task = Task.Run(async () => (TResult)await revitTask.tcs.Task);
        revitTask.handler.SetFunc(func, param1, param2, param3, param4, param5);
        revitTask.externalEvent.Raise();
        return task;
    }

    /// <summary>
    /// 执行可以返回数据的外部事件任务
    /// </summary>
    /// <typeparam name="T1"></typeparam>
    /// <typeparam name="T2"></typeparam>
    /// <typeparam name="T3"></typeparam>
    /// <typeparam name="T4"></typeparam>
    /// <typeparam name="T5"></typeparam>
    /// <typeparam name="T6"></typeparam>
    /// <typeparam name="TResult"></typeparam>
    /// <param name="revitTask"></param>
    /// <param name="param1"></param>
    /// <param name="param2"></param>
    /// <param name="param3"></param>
    /// <param name="param4"></param>
    /// <param name="param5"></param>
    /// <param name="param6"></param>
    /// <param name="func"></param>
    /// <returns></returns>
    public static Task<TResult> RunAsync<T1, T2, T3, T4, T5, T6, TResult>(this ExternalEventTask revitTask, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, Func<UIApplication, T1, T2, T3, T4, T5, T6, TResult> func)
    {
        revitTask.tcs = new TaskCompletionSource<object>();
        var task = Task.Run(async () => (TResult)await revitTask.tcs.Task);
        revitTask.handler.SetFunc(func, param1, param2, param3, param4, param5, param6);
        revitTask.externalEvent.Raise();
        return task;
    }

    /// <summary>
    /// 执行可以返回数据的外部事件任务
    /// </summary>
    /// <typeparam name="T1"></typeparam>
    /// <typeparam name="T2"></typeparam>
    /// <typeparam name="T3"></typeparam>
    /// <typeparam name="T4"></typeparam>
    /// <typeparam name="T5"></typeparam>
    /// <typeparam name="T6"></typeparam>
    /// <typeparam name="T7"></typeparam>
    /// <typeparam name="TResult"></typeparam>
    /// <param name="revitTask"></param>
    /// <param name="param1"></param>
    /// <param name="param2"></param>
    /// <param name="param3"></param>
    /// <param name="param4"></param>
    /// <param name="param5"></param>
    /// <param name="param6"></param>
    /// <param name="param7"></param>
    /// <param name="func"></param>
    /// <returns></returns>
    public static Task<TResult> RunAsync<T1, T2, T3, T4, T5, T6, T7, TResult>(this ExternalEventTask revitTask, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, Func<UIApplication, T1, T2, T3, T4, T5, T6, T7, TResult> func)
    {
        revitTask.tcs = new TaskCompletionSource<object>();
        var task = Task.Run(async () => (TResult)await revitTask.tcs.Task);
        revitTask.handler.SetFunc(func, param1, param2, param3, param4, param5, param6, param7);
        revitTask.externalEvent.Raise();
        return task;
    }
}
